#!/bin/bash

# 默认值
ALL_FILES_MODE=false
INCLUDE_UNTRACKED=true
DRY_RUN=false
COMMIT_HASH=""  # 默认为空，表示只处理工作区修改

# 显示帮助信息
show_help() {
    echo "文件清理脚本 - 自动化清理代码格式问题"
    echo ""
    echo "用法: $0 [选项] [<commit-hash>]"
    echo ""
    echo "选项:"
    echo "  -f          强制处理所有文件类型（包括二进制文件）"
    echo "  -n          排除未跟踪文件处理"
    echo "  -u          包含未跟踪文件（默认行为）"
    echo "  -d, --dry-run  模拟运行，显示操作但不修改文件"
    echo "  -h, --help     显示此帮助信息"
    echo ""
    echo "功能说明:"
echo "  本脚本执行以下操作："
echo "  1. 转换Windows格式行尾为Unix格式 (dos2unix)"
echo "  2. 移除行尾空白字符"
echo "  3. (可选)处理指定提交以来的所有修改文件和未跟踪文件"
echo ""
echo "默认行为:"
echo "  不输入commit-hash时，只处理工作区中已修改但未提交的文件"
echo "  默认只处理文本文件（跳过二进制文件）"
    echo ""
    echo "示例:"
    echo "  $0 -f              # 强制模式处理最近提交的所有文件"
    echo "  $0 -n a1b2c3d4     # 排除未跟踪文件处理指定提交"
    echo "  $0 --dry-run       # 模拟运行但不修改文件"
    exit 0
}

# 解析命令行选项
while [[ $# -gt 0 ]]; do
    case "$1" in
        -f)
            ALL_FILES_MODE=true
            shift
            ;;
        -n)
            INCLUDE_UNTRACKED=false
            shift
            ;;
        -u)
            INCLUDE_UNTRACKED=true
            shift
            ;;
        -d|--dry-run)
            DRY_RUN=true
            shift
            ;;
        -h|--help)
            show_help
            ;;
        *)
            # 处理可选参数
            if [[ $# -eq 1 ]]; then
                COMMIT_HASH="$1"
            else
                echo "错误: 无效选项或参数: $1"
                show_help
                exit 1
            fi
            shift
            ;;
    esac
done

# 设置文本文件扩展名
TEXT_FILE_EXTS=("txt" "md" "py" "sh" "js" "vue" "java" "c" "cpp" "h" "html" "css" "xml" "yml" "yaml" "conf" "ini" "php")

# 检查是否为文本文件
is_text_file() {
    local file=$1

    # 开关模式强制处理所有文件
    $ALL_FILES_MODE && return 0

    # 通过扩展名判断
    local ext="${file##*.}"
    [[ " ${TEXT_FILE_EXTS[*]} " =~ " ${ext} " ]] && return 0

    # 通过file命令检测MIME类型
    if file -b --mime-type "$file" | grep -qE '^text/'; then
        return 0
    fi

    return 1
}

echo "== 文件清理脚本 =="
echo "模式:"
echo "  - 强制模式: $([ "$ALL_FILES_MODE" = true ] && echo '开启' || echo '关闭')"
echo "  - 包含未跟踪文件: $([ "$INCLUDE_UNTRACKED" = true ] && echo '是' || echo '否')"
echo "  - 模拟运行: $([ "$DRY_RUN" = true ] && echo '是' || echo '否')"
if [ -n "$COMMIT_HASH" ]; then
    echo "  - Commit基准: $COMMIT_HASH"
else
    echo "  - 处理范围: 工作区修改文件"
fi
echo ""

# 函数：处理单个文件
process_file() {
    local file="$1"
    local reason="$2"
    local action_taken=false

    if [ ! -f "$file" ]; then
        echo "跳过不存在文件: $file"
        return
    fi

    if is_text_file "$file"; then
        if $DRY_RUN; then
            echo "✓ (模拟)文本文件将处理: $file - $reason"
        else
            # 执行dos2unix转换行尾格式
            dos2unix -q "$file" && action_taken=true
            # 移除行尾空白字符
            sed -i -E 's/[[:space:]]+$//' "$file" && action_taken=true

            if $action_taken; then
                echo "✓ 已处理文本文件: $file - $reason"
            else
                echo "⚠ 文本文件无更改: $file - $reason"
            fi
        fi
    elif $ALL_FILES_MODE; then
        if $DRY_RUN; then
            echo "⚠ (模拟)非文本文件将处理: $file - $reason（强制模式）"
        else
            # 对非文本文件执行操作
            dos2unix -q "$file" && action_taken=true
            sed -i -E 's/[[:space:]]+$//' "$file" && action_taken=true

            if $action_taken; then
                echo "⚠ 已处理非文本文件: $file - $reason（强制模式）"
            else
                echo "⚠ 非文本文件无更改: $file - $reason（强制模式）"
            fi
        fi
    else
        echo "✗ 跳过非文本文件: $file - $reason（使用 -f 覆盖）"
    fi
}

# 处理修改过的文件
if [ -n "$COMMIT_HASH" ]; then
    if $DRY_RUN; then
        echo ">> (模拟)处理修改文件 (从 $COMMIT_HASH 以来的变更)..."
    else
        echo ">> 处理修改文件 (从 $COMMIT_HASH 以来的变更)..."
    fi
    git diff --name-only "$COMMIT_HASH" | while IFS= read -r file; do
        process_file "$file" "修改"
    done
else
    if $DRY_RUN; then
        echo ">> (模拟)处理工作区修改文件..."
    else
        echo ">> 处理工作区修改文件..."
    fi
    git diff --name-only | while IFS= read -r file; do
        process_file "$file" "工作区修改"
    done
fi

# 处理未跟踪文件
if $INCLUDE_UNTRACKED; then
    echo ""
    if $DRY_RUN; then
        echo ">> (模拟)处理未跟踪文件..."
    else
        echo ">> 处理未跟踪文件..."
    fi
    git ls-files --others --exclude-standard | while IFS= read -r file; do
        process_file "$file" "未跟踪"
    done
fi

echo ""
if $DRY_RUN; then
    echo "== 模拟运行完成！实际文件未被修改 =="
    echo "提示: 移除--dry-run选项以实际执行操作"
else
    echo "== 操作完成！ =="
    echo "提示: 使用git diff检查修改，或添加--dry-run选项进行模拟运行"
fi
